package com.DosonLeung.homeschoolcommunication.Models;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.DosonLeung.homeschoolcommunication.Components.ChatsAdapter;
import com.DosonLeung.homeschoolcommunication.Components.CommonAdapter;
import com.DosonLeung.homeschoolcommunication.Constant.SystemConstant;
import com.DosonLeung.homeschoolcommunication.Constant.UrlConstant;
import com.DosonLeung.homeschoolcommunication.Constant.UserConstant;
import com.DosonLeung.homeschoolcommunication.Controllers.ChatActivity;
import com.DosonLeung.homeschoolcommunication.R;
import com.DosonLeung.homeschoolcommunication.SQLite.MembersDB;
import com.DosonLeung.homeschoolcommunication.Utils.NetWorkUtil;
import com.DosonLeung.homeschoolcommunication.Utils.StorageUtil;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
 * Created by DosonLeung on 2014/11/9.
 */
public class MainModel {

    //当前Model的环境
    Activity app;
    //与MainActivity沟通的Handler
    Handler mHandler;
    //与Service沟通的Handler
    Handler serviceHandler;
    //使用者角色
    String userCharacter;
    //家长、老师数据库Connection
    MembersDB membersDB;
    //一班级其他成员的信息的数据链表
    LinkedList<Map<String, String>> membersList;
    //班级的列表，供老师使用
    LinkedList<Map<String, String>> classList;
    //一班级其他成员的聊天记录的数据链表
    LinkedList<Map<String, String>> chatsList;
    //从远程获取的同一班级其他成员的信息的JSONArray
    JSONArray jsonArray;
    //家长版聊天记录视图pChatsList
    ListView pChatsListView;
    //家长版联系人记录视图pContactList
    ListView pContactsListView;
    //老师版班级记录视图tChatList
    ListView tClassListView;
    //老师版聊天记录视图tChatList
    ListView tChatsListView;
    //老师版联系人记录视图tContactList
    ListView tContactsListView;
    //家长版聊天视图适配器Adapter
    ChatsAdapter pChatsAdapter;
    //家长版联系人视图适配器Adapter
    CommonAdapter pContactsAdapter;
    //老师版班级试图的适配器Adapter
    CommonAdapter tClassAdapter;
    //老师版聊天视图的适配器Adapter
    ChatsAdapter tChatsAdapter;
    //老师版联系人视图适配器Adapter
    CommonAdapter tContactsAdapter;

    public MainModel(Activity app, String Character, Handler mHandler) {
        this.app = app;
        this.mHandler = mHandler;
        this.userCharacter = Character;
        this.membersList = new LinkedList<Map<String, String>>();
        this.classList = new LinkedList<Map<String, String>>();
        this.membersDB = new MembersDB(this.app, StorageUtil.getChatDir().toString() + "/" + "members.db3", 1);
    }

    public void setServiceHandler(Handler serviceHandler) {
        this.serviceHandler = serviceHandler;
    }

    public void settContactsListView(ListView tContactsListView) {
        this.tContactsListView = tContactsListView;
    }

    public void setpChatsListView(ListView pChatsListView) {
        this.pChatsListView = pChatsListView;
    }

    public void setpContactsListView(ListView pContactsListView) {
        this.pContactsListView = pContactsListView;
    }

    public void settChatsListView(ListView tChatsListView) {
        this.tChatsListView = tChatsListView;
    }

    public void settClassListView(ListView tClassListView) {
        this.tClassListView = tClassListView;
    }

    public LinkedList<Map<String, String>> getMemberList(){
        return membersList;
    }

    public void init() {
        refreshAllDataList(false);//第一次为false，表示尝试从数据库获取数据
        if (this.membersList.size() == 0) {
            refreshAllDataList(true);
            initViews("contacts", this.membersList);
            initViews("chats", this.chatsList);
            initViews("classes", this.classList);
            initListeners();
        } else {
            mHandler.sendEmptyMessage(0x200);//无须
        }
    }

    private void initListeners() {
        if (UserConstant.USER_CHARACTER.equalsIgnoreCase("patriarch")) {
            pContactsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    String uid = getUidByPosition("members", position);
                    String avatar_path = getUrlByPosition("members", position);
                    String type = getRoleByPosition("members", position);
                    SystemConstant.clearNewInRegister(uid);
                    if (type.equals("class")) {
                        itemOnclick(uid, avatar_path, false, true);
                    } else {
                        itemOnclick(uid, avatar_path, false, false);
                    }
                }
            });
            pChatsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    String uid = getUidByPosition("chats", position);
                    String avatar_path = getUrlByPosition("chats", position);
                    String type = getRoleByPosition("chats", position);
                    SystemConstant.clearNewInRegister(uid);
                    if (type.equals("class")) {
                        itemOnclick(uid, avatar_path, false, true);
                    } else {
                        itemOnclick(uid, avatar_path, false, false);
                    }
                }
            });
        } else if (UserConstant.USER_CHARACTER.equals("teacher")) {
            tContactsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    String uid = getUidByPosition("members", position);
                    String avatar_path = getUrlByPosition("members", position);
                    String type = getRoleByPosition("members", position);
                    SystemConstant.clearNewInRegister(uid);
                    if (type.equals("class")) {
                        itemOnclick(uid, avatar_path, false, true);
                    } else {
                        itemOnclick(uid, avatar_path, false, false);
                    }
                }
            });
            tChatsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    String uid = getUidByPosition("chats", position);
                    String avatar_path = getUrlByPosition("chats", position);
                    String type = getRoleByPosition("chats", position);
                    SystemConstant.clearNewInRegister(uid);
                    if (type.equals("class")) {
                        itemOnclick(uid, avatar_path, false, true);
                    } else {
                        itemOnclick(uid, avatar_path, false, false);
                    }
                }
            });
            tClassListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                    String cid = getUidByPosition("classes", position);
                    String avatar_path = getUrlByPosition("classes", position);
                    String type = getRoleByPosition("classes", position);
                    SystemConstant.clearNewInRegister(cid);
                    if (type.equals("class")) {
                        itemOnclick(cid, avatar_path, true, true);
                    } else {
                        itemOnclick(cid, avatar_path, true, false);
                    }
                }
            });
        } else {
            Log.e("MainModel:initListeners", "you haven't choose a type yet!");
        }
    }

    //绑定所有的view并初始化
    private void initViews(String tab, LinkedList<Map<String, String>> itemList) {
        int resource = 0;
        String from[] = {};
        int to[] = {};
        if (UserConstant.USER_CHARACTER.equals("patriarch")) {
            if (tab.equalsIgnoreCase("contacts")) {
                resource = R.layout.p_contact_item;
                from = new String[]{"avatar_path", "name", "role", "lasttime"};
                to = new int[]{R.id.p_contact_icon, R.id.p_contact_name, R.id.p_contact_subject, R.id.p_contact_time};
                this.pContactsAdapter = new CommonAdapter(app, itemList, resource, from, to, mHandler);
                if (pContactsListView != null) {
                    pContactsListView.setAdapter(this.pContactsAdapter);
                    fixListViewHeight(pContactsListView);
                } else
                    Log.e("MainModel", "pContactsListView is null!");
            } else if (tab.equalsIgnoreCase("chats")) {
                resource = R.layout.p_chats_item;
                from = new String[]{"avatar_path", "name", "lastnote", "lasttime", "Sum"};
                to = new int[]{R.id.p_chats_icon, R.id.p_chats_name, R.id.p_chats_lastnote, R.id.p_chats_lasttime, R.id.p_chats_sum};
                this.pChatsAdapter = new ChatsAdapter(app, itemList, resource, from, to);
                if (pChatsListView != null) {
                    pChatsListView.setAdapter(this.pChatsAdapter);
                    fixListViewHeight(pChatsListView);
                }else
                    Log.e("MainModel", "pChatsListView is null!");
            }
        } else if (UserConstant.USER_CHARACTER.equals("teacher")) {
            if (tab.equalsIgnoreCase("contacts")) {
                resource = R.layout.t_contact_item;
                from = new String[]{"avatar_path", "name", "role", "lasttime"};
                to = new int[]{R.id.t_contact_icon, R.id.t_contact_name, R.id.t_contact_salutation, R.id.t_contact_time};
                this.tContactsAdapter = new CommonAdapter(app, itemList, resource, from, to, mHandler);
                if (tContactsListView != null) {
                    tContactsListView.setAdapter(this.tContactsAdapter);
                    fixListViewHeight(tContactsListView);
                } else
                    Log.e("MainModel", "tContactsListView is null!");
            } else if (tab.equalsIgnoreCase("chats")) {
                resource = R.layout.t_chats_item;
                from = new String[]{"avatar_path", "name", "lastnote", "lasttime", "Sum"};
                to = new int[]{R.id.t_chats_icon, R.id.t_chats_name, R.id.t_chats_lastnote, R.id.t_chats_lasttime, R.id.t_chats_sum};
                this.tChatsAdapter = new ChatsAdapter(app, itemList, resource, from, to);
                if (tChatsListView != null) {
                    tChatsListView.setAdapter(this.tChatsAdapter);
                    fixListViewHeight(tChatsListView);
                }
                else
                    Log.e("MainModel", "tChatsListView is null!");
            } else if (tab.equals("classes")) {
                resource = R.layout.t_class_item;
                from = new String[]{"avatar_path", "name", "description"};
                to = new int[]{R.id.class_icon, R.id.class_name};
                this.tClassAdapter = new CommonAdapter(app, itemList, resource, from, to, mHandler);
                if (tClassListView != null) {
                    tClassListView.setAdapter(this.tClassAdapter);
                    fixListViewHeight(tClassListView);
                } else
                    Log.e("MainModel", "tClassListView is null!");
            }
        }
    }

    public void notifyAllViews() {
        if (UserConstant.USER_CHARACTER.equalsIgnoreCase("patriarch")) {
            initViews("contacts", this.membersList);
            initViews("chats", this.chatsList);
            //Toast.makeText(app,"更新了视图",Toast.LENGTH_SHORT).show();
            initListeners();
        } else if (UserConstant.USER_CHARACTER.equals("teacher")) {
            initViews("contacts", this.membersList);
            initViews("chats", this.chatsList);
            initViews("classes", this.classList);
            //Toast.makeText(app,"更新了视图",Toast.LENGTH_SHORT).show();
            initListeners();
        } else {
            Log.e("MainModel:initListeners", "you haven't choose a type yet!");
        }
    }

    /*
   *
   * 若参数forceToRefreshByNetWork为false
   * 获取同一班级的所有其他成员的信息，如果本地为空，但这些数据链表将会为空，render()不调用
   * 并且从远程获取，获取完毕后填充数据链表，并渲染
   * 若参数forceToRefreshByNetWork为true
   * 强制从远程获取获取同一班级的所有其他成员的信息并更新
   * **/
    public void refreshAllDataList(boolean forceToRefreshByNetWork) {
        int size;
        Map<String, String> item;
        LinkedList<Map<String, String>> list;
        if (forceToRefreshByNetWork) {
            getPersonDataByNetWork(this.mHandler);
            return;
        } else {
            list = this.membersDB.getMembersData();
        }
        chatsList = new LinkedList<Map<String, String>>();
        membersList = new LinkedList<Map<String, String>>();
        classList = new LinkedList<Map<String, String>>();
        size = list.size();
        for (int i = 0; i < size; i++) {
            item = list.get(i);
            String lastnote = (item.get("lastnote"));
            String type = (item.get("type"));
            String uid = item.get("uid");
            if (type.equals("class")) {
                classList.add(item);
            } else {
                membersList.add(item);
            }
            if ((!(lastnote.equals("无")))) {
                item.put("Sum", SystemConstant.getSumByUid(uid));
                this.chatsList.add(item);
            }
        }
    }

    /**
     * 当CommonAdapter的一个图片加载线程完成后，通知MainActivity调用该方法
     * 异步更改其中的图片的内容
     */
    public void asyncNotifyView() {
        if (UserConstant.USER_CHARACTER.equalsIgnoreCase("patriarch")) {
            int lastIndex = this.pContactsAdapter.getBitmapList().size() - 1;
            try {
                HashMap<String, Object> item = this.pContactsAdapter.getBitmapList().get(lastIndex);
                Integer index = (Integer) item.get("index");
                Bitmap bitmap = (Bitmap) item.get("bitmap");
                (this.pContactsAdapter.getImageList().get(index)).setImageBitmap(bitmap);
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        } else if (UserConstant.USER_CHARACTER.equals("teacher")) {
            int lastIndex = this.tContactsAdapter.getBitmapList().size() - 1;
            try {
                HashMap<String, Object> item = this.tContactsAdapter.getBitmapList().get(lastIndex);
                Integer index = (Integer) item.get("index");
                Bitmap bitmap = (Bitmap) item.get("bitmap");
                (this.tContactsAdapter.getImageList().get(index)).setImageBitmap(bitmap);
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        } else {
            Log.e("MainModel:initListeners", "you haven't choose a type yet!");
        }
    }

    private void update(String role, int position, String key, String detail) {
        Map<String, String> item;
        item = this.membersList.get(position);
        item.remove(key);
        item.put(key, detail);
        membersDB.update(item);
        membersList.set(position, item);
    }

    //通过ID跟新联系人信息
    public boolean update(String role, String ID, String key, String detail) {
        int index = 0;
        int length;
        Map<String, String> member;
        length = membersList.size();
        for (int i = 0; i < length; i++) {
            member = membersList.get(i);
            if (member.get("uid").equalsIgnoreCase(ID)) {
                index = i;
                break;
            }
        }
        if (index < 0) {
            return false;
        } else {
            update(role, index, key, detail);
        }
        return true;
    }

    /*
    * 插入操作(type 指类型（个人false、班级true），item 指数据项)
    * 先插入到数据库，无论是个人还是班级，都平等插入到数据库
    * 再插入到数据链表
    * **/
    public void insert(Map<String, String> item, boolean type) {
        membersDB.insert(item);
        if (type)
            this.classList.add(item);
        else
            this.membersList.add(item);
    }

    //删除联系人记录
    public boolean delete() {
        return false;
    }

    private void getPersonDataByNetWork(final Handler mHandler) {
        final String url = String.format(UrlConstant.getPersonUrl, UserConstant.USER_ACCOUNT, UserConstant.USER_PASSWORD);
        new Thread() {
            @Override
            public void run() {
                Message msg = new Message();
                mHandler.sendEmptyMessage(0x300);
                try {
                    String otherPerson = NetWorkUtil.httpGet(url);
                    if (otherPerson != null) {
                        jsonArray = new JSONArray(otherPerson);
                        int sum = jsonArray.length();//班级个数
                        for (int i = 0; i < sum; i++) {
                            JSONObject jsonObject = jsonArray.getJSONObject(i);
                            UserConstant.CLASS_ID_LIST.add(jsonObject.getString("cid"));
                            jsonArray = jsonObject.getJSONArray("members");
                            formatClassData(jsonObject);//插入班级链表
                            formatMembersData(i);//插入成员链表
                        }
                        msg.what = 0x200;
                    } else {
                        msg.what = 0x404;
                    }
                    mHandler.sendMessage(msg);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    mHandler.sendEmptyMessage(0x500);
                }
            }
        }.start();
    }

    private void formatClassData(JSONObject jsonObject) {
        HashMap<String, String> classMap = null;
        try {
            classMap = new HashMap<String, String>();
            classMap.put("uid", jsonObject.getString("cid") + UserConstant.USER_ID);//为了防止cid与uid冲突，uid为cid＋uid
            classMap.put("name", jsonObject.getString("name"));//班级的名字
            classMap.put("avatar_path", jsonObject.getString("avatar_path"));// 班级的头像
            classMap.put("sex", "3");//班级性别为3
            classMap.put("phone", "无");//
            classMap.put("role", "无");
            classMap.put("type", "class");// 个人的话这里都会有"1"或者"2"，班级是String:"class"
            classMap.put("classid", jsonObject.getString("cid"));
            classMap.put("description", "无");
            classMap.put("lasttime", "无");
            classMap.put("lastnote", "无");
            classMap.put("lastnotetype", "无");
            NetWorkUtil.startloaImageThread(jsonObject.getString("avatar_path"), "50");
        } catch (Exception e) {
            e.printStackTrace();
        }
        insert(classMap, true);
    }

    //当家长账号从远程下载本地时，进行格式转换,index是指第index个班级
    private void formatMembersData(int index) {
        int length = jsonArray.length();
        JSONObject jsonObject = null;
        String type;
        HashMap<String, String> membersMap = null;
        for (int i = 0; i < length; i++) {
            try {
                jsonObject = jsonArray.getJSONObject(i);
                membersMap = new HashMap<String, String>();
                type = jsonObject.getString("type");//1 家长 2 老师
                if (UserConstant.USER_CHARACTER.equals("patriarch")) {//家长则过滤家长
                    if (type.equals("1"))
                        continue;
                } else {//老师则过滤老师,但头像依然下载
                    if (type.equals("2")) {
                        NetWorkUtil.startloaImageThread(jsonObject.getString("avatar_path"), "50");
                        continue;
                    }
                }
                membersMap.put("uid", jsonObject.getString("uid"));
                membersMap.put("name", jsonObject.getString("name"));
                membersMap.put("avatar_path", jsonObject.getString("avatar_path"));
                membersMap.put("sex", jsonObject.getString("sex"));
                membersMap.put("phone", jsonObject.getString("phone"));
                membersMap.put("type", jsonObject.getString("type"));
                membersMap.put("role", jsonObject.getString("role"));
                membersMap.put("classid", UserConstant.CLASS_ID_LIST.get(index));
                membersMap.put("description", jsonObject.getString("description"));
                membersMap.put("lasttime", "无");
                membersMap.put("lastnote", "无");
                membersMap.put("lastnotetype", "无");
                NetWorkUtil.startloaImageThread(jsonObject.getString("avatar_path"), "50");
            } catch (Exception e) {
                e.printStackTrace();
            }
            insert(membersMap, false);
        }
    }

    //check为true,在membersList查找，false在chatList里查找
    private String getUidByPosition(String check, int index) {
        String uid = "";
        if (check.equals("members"))
            uid = membersList.get(index).get("uid");
        else if (check.equals("chats"))
            uid = chatsList.get(index).get("uid");
        else if (check.equals("classes"))
            uid = classList.get(index).get("uid");
        return uid;
    }

    //获取对方的头像地址，同上
    private String getUrlByPosition(String check, int index) {
        String avatar_path = "";
        if (check.equals("members"))
            avatar_path = membersList.get(index).get("avatar_path");
        else if (check.equals("chats"))
            avatar_path = chatsList.get(index).get("avatar_path");
        else if (check.equals("classes")) {
            avatar_path = classList.get(index).get("avatar_path");
        }
        return avatar_path;
    }

    //获取点击的信息类型（返回false:个人，true:班级 ）
    private String getRoleByPosition(String check, int index) {
        String type = "";
        if (check.equals("members"))
            type = membersList.get(index).get("type");
        else if (check.equals("chats"))
            type = chatsList.get(index).get("type");
        else if (check.equals("classes"))
            type = classList.get(index).get("type");
        return type;
    }

    //联系人或者消息列表点击Item事件,tab表示列表类型（true:个人列表 false:班级列表），表示点击信息的类型（true:个人信息 false:班级信息）
    private void itemOnclick(String uid, String avatar_path, boolean tab, boolean type) {
        Bundle data = new Bundle();
        data.putString("targetId", uid);//如果是班级,uid=cid+UserConstant.USER_ID,如果是个人,uid=发送者uid
        Message msg = new Message();
        msg.setData(data);
        msg.what = 0x201;
        serviceHandler.sendMessage(msg);//上段是对service的通知
        Intent intent = new Intent(app, ChatActivity.class);
        intent.putExtra("target", uid);//如果是班级,uid=cid+UserConstant.USER_ID,如果是个人,uid=发送者uid
        intent.putExtra("avatar_path", avatar_path);
        intent.putExtra("tab", tab);
        intent.putExtra("type", type);
        app.startActivityForResult(intent, SystemConstant.CHAT_CODE);
    }

    public void fixListViewHeight(ListView listView) {
        // 如果没有设置数据适配器，则ListView没有子项，返回。
        ListAdapter listAdapter = listView.getAdapter();
        int totalHeight = 0;
        if (listAdapter == null) {
            return;
        }
        for (int index = 0, len = listAdapter.getCount(); index < len; index++) {
            View listViewItem = listAdapter.getView(index, null, listView);
            // 计算子项View 的宽高
            listViewItem.measure(0, 0);
            // 计算所有子项的高度和
            totalHeight += listViewItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        // listView.getDividerHeight()获取子项间分隔符的高度
        // params.height设置ListView完全显示需要的高度
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }

    public void closeMemberDB(){
        if(membersDB!=null)
            membersDB.close();
    }
}
